

package examples.basic;

import commandz.cli.*;
import commandz.var.Variable;
import java.io.*;


/**
 *  Basic example of using the commandz-package.
 *
 *  This application reads and executes commands like the
 *  command-processor of most operating systems do.
 */
public final class Example implements Runnable, InterpreterFeedback
{
    /*
     *  A literal containing a message to inform the user when this
     *  example application starts.
     */
    private static final String banner =
        "\nCommand-interpreter example application v1.0\n" +
        "Type 'list' for information.\n\n";

    /*
     *  A literal that represents a prompt which is used when reading
     *  commands from the standard input-stream.
     */
    private static final String prompt = "> ";

    /*
     *  Indicates whether to continue the interpretation of commands
     *  or not.
     */
    private boolean exit;


    /**
     *  Performs a notification of a argument parse error.
     */
    public void argumentError(final Interpreter source, final Command cmd,
                              final Parameter param, final String argument)
    {
        Variable var = param.getVariable();

        System.out.printf("%s: argument \"%s\" is not a valid value " +
                          "for %s parameter \"%s\".\n", cmd.getName(),
                          argument, var.getTypeName(), param.getName());
    }


    /**
     *  Performs a notification of a argumentation mismatch.
     */
    public void argumentMismatch(final Interpreter source, final Command cmd,
                                 final int expected, final int provided)
    {
        if (expected == 0)  // no arguments required
        {
            System.out.printf("%s: no arguments expected.\n", cmd.getName());
            return;
        }

        if (expected == 1)  // one argument required
        {
            System.out.printf("%s: argument expected.\n", cmd.getName());
            return;
        }

        System.out.printf("%s: %d arguments expected.\n", cmd.getName(), expected);
    }


    /**
     *  Performs a notification of a unknown command error.
     */
    public void unknownCommand(final Interpreter source, final String identifier)
    {
        System.out.printf("%s: unknown command.\n", identifier);
    }


    /**
     *  Interrupts the operation of this Example.
     */
    public void stop()
    {
        this.exit = true;
    }


    /**
     *  Runs the example.
     */
    public void run()
    {
        System.out.print(this.banner);

        Interpreter interpreter = new Interpreter(this);
        interpreter.recognize(new ListCommand(interpreter));
        interpreter.recognize(new HelpCommand(interpreter));
        interpreter.recognize(new AliasCommand(interpreter));
        interpreter.recognize(new ExitCommand(this));
        interpreter.recognize(new EchoCommand());

        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        this.exit = false;

        do  // parse and execute commands..
        {
            String line;

            System.out.print(this.prompt);

            try // to read a line of text..
            {
                line = input.readLine();
            }
            catch (IOException error)
            {
                break;
            }

            if (line == null)  // end of input?
                break;

            interpreter.interpret(line);
        }
        while (!this.exit);

        System.out.println("bye.");
    }


    /**
     *  Program entry point.
     */
    public static void main(String argv[])
    {
        Runnable example = new Example();
        example.run();
    }

}
